package com.base.cn.platform.os.service.course.open;

import com.base.cn.platform.os.common.constants.ConfigName;
import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.service.CommonSetCreateUserDataService;
import com.base.cn.platform.os.common.service.CommonSetSubjectDataService;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.TT.TTServiceUtils;
import com.base.cn.platform.os.dao.course.open.CourseOpenDao;
import com.base.cn.platform.os.entity.course.count.CourseOpenSumCount;
import com.base.cn.platform.os.entity.course.material.CouMaterial;
import com.base.cn.platform.os.entity.course.open.CourseOpen;
import com.base.cn.platform.os.entity.course.open.CourseOpenBespeak;
import com.base.cn.platform.os.entity.course.open.CourseOpenCondition;
import com.base.cn.platform.os.service.manage.config.SysConfigService;
import com.base.cn.platform.os.service.manage.subject.SubjectService;
import com.base.cn.platform.os.service.manage.sysUser.SysUserService;
import com.base.cn.platform.os.service.manage.teacher.SysTeacherService;
import com.base.cn.platform.os.service.manage.user.user.CusUserService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 免费直播课程Biz
 *
 * @author s.li
 * @create 2018-05-03-15:23
 */
@Service
public class CourseOpenBiz extends BaseBiz<CourseOpen,CourseOpenDao> {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SubjectService subjectService;
    @Autowired
    private CommonSetCreateUserDataService<CourseOpen> commonSetCreateUserDataService;
    @Autowired
    private CommonSetSubjectDataService<CourseOpen> commonSetSubjectDataService;
    @Autowired
    private SysTeacherService sysTeacherService;
    @Autowired
    private CourseOpenBespeakBiz courseOpenBespeakBiz;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private CourseOpenDao courseOpenDao;
    @Autowired
    private CusUserService cusUserService;
    @Autowired
    private TTServiceUtils ttServiceUtils;

    /**
     * 查询多条件免费直播数量
     * @param condition 查询条件对象
     * @return 数量
     */
    public BigDecimal getCourseOpenCount(CourseOpenCondition condition){
        String whereSql = this.getWhereSql(condition);
        return this.count(whereSql);
    }

    /**
     * 保存免费直播课程
     * @param courseOpen 免费直播课程对象
     * @return CourseOpen
     */
    public CourseOpen saveCourseOpen(CourseOpen courseOpen){
        if(DataUtil.idIsNotNull(courseOpen.getId())){//修改
            this.updateById(courseOpen,null);
        }else{//添加
            courseOpen.setStatus(1);
            courseOpen.setId(null);
            this.save(courseOpen);
        }
        return courseOpen;
    }

    /**
     * 保存免费直播描述信息
     * @param courseOpen 免费直播数据对
     * @return CourseOpen
     */
    public CourseOpen saveCourseOpenInfo(CourseOpen courseOpen){
        CourseOpen _courseOpen = this.findById(courseOpen.getId());
        _courseOpen.setTrait(courseOpen.getTrait());//免费直播特点
        _courseOpen.setSuitableUser(courseOpen.getSuitableUser());//适宜学员
        _courseOpen.setDetails(courseOpen.getDetails());//免费直播详情
        this.updateById(_courseOpen,null);
        return _courseOpen;
    }

    /**
     * 修改免费直播状态
     * @param ids 免费直播ID
     * @param status 1：正常 2：冻结 3：删除
     */
    public void updateCourseOpenStatus(String ids,int status){
        if(StringUtils.isNotEmpty(ids)){
            ids = StringUtils.subHeadTailString(ids,",");
            if(StringUtils.isNotEmpty(ids)){
                CourseOpen courseOpen = new CourseOpen();
                courseOpen.setStatus(status);
                this.updateByWhereSql(courseOpen," id in ("+ids+")");
            }
        }
    }

    /**
     * 通过ID，查询免费直播数据对象
     * @param id 免费直播ID
     * @param setSubjectData 是否设置专业
     * @param setTeacherData 是否设置讲师
     * @param setCreateUserData 是否设置创建人数据
     * @return CourseOpen
     */
    public CourseOpen findCourseOpenById(BigDecimal id,boolean setSubjectData,boolean setTeacherData,boolean setCreateUserData){
        List<CourseOpen> courseOpenList = this.findCourseOpenListByIds(id.toString(),setSubjectData,setTeacherData,setCreateUserData);
        if(ObjectUtils.isNotEmpty(courseOpenList)){
            return courseOpenList.get(0);
        }
        return null;
    }

    /**
     * 通过ID串，查询免费直播数据Map
     * @param ids 免费直播ID串
     * @param setSubjectData 是否设置专业
     * @param setTeacherData 是否设置讲师
     * @param setCreateUserData 是否设置创建人数据
     * @return List<CourseOpen>
     */
    public  Map<BigDecimal,CourseOpen> findCourseOpenMapByIds(String ids,boolean setSubjectData,boolean setTeacherData,boolean setCreateUserData){
        List<CourseOpen> courseOpenList = this.findCourseOpenListByIds(ids,setSubjectData,setTeacherData,setCreateUserData);
        if(ObjectUtils.isNotEmpty(courseOpenList)){
            Map<BigDecimal,CourseOpen> courseOpenMaps = courseOpenList.stream().collect(Collectors.toMap(e->e.getId(),e->e));
            return courseOpenMaps;
        }
        return null;
    }

    /**
     * 通过ID串，查询免费直播数据列表
     * @param ids 免费直播ID串
     * @param setSubjectData 是否设置专业
     * @param setTeacherData 是否设置讲师
     * @param setCreateUserData 是否设置创建人数据
     * @return List<CourseOpen>
     */
    public List<CourseOpen> findCourseOpenListByIds(String ids ,boolean setSubjectData,boolean setTeacherData,boolean setCreateUserData){
        CourseOpenCondition condition = new CourseOpenCondition();
        condition.setQueryIds(ids);
        List<CourseOpen> courseOpenList = this.findCourseOpenList(condition,setSubjectData,false,setTeacherData,setCreateUserData);
        return courseOpenList;
    }

    /**
     * 多条件查询免费直播数据列表
     * @param condition 查询条件对象
     * @param setSubjectData 是否设置专业
     * @param setTeacherData 是否设置讲师
     * @param setCreateUserData 是否设置创建人数据
     * @return List<CourseOpen>
     */
    public List<CourseOpen> findCourseOpenList(CourseOpenCondition condition,
                                               boolean setSubjectData,boolean setReservationData,boolean setTeacherData,boolean setCreateUserData){
        BigDecimal userId = condition.getUserId();
        List<CourseOpen> courseOpenList = this.find(this.getWhereSql(condition),condition.getCount(),null);
        this.setCourseOpenExData(courseOpenList,userId,setSubjectData,setReservationData,setTeacherData,setCreateUserData);
        return courseOpenList;
    }

    /**
     * 分页查询免费直播数据列表
     * @param condition 查询条件对象
     * @param page 分页条件对象
     * @param setSubjectData 是否设置专业
     * @param setTeacherData 是否设置讲师
     * @param setCreateUserData 是否设置创建人数据
     * @return PageInfo<CourseOpen>
     */
    public PageInfo<CourseOpen> findCourseOpenPage(CourseOpenCondition condition, Pagination page,
                                                   boolean setSubjectData,boolean setReservationData,boolean setTeacherData,boolean setCreateUserData){
        BigDecimal userId = condition.getUserId();
        PageInfo<CourseOpen> courseOpenPageInfo = this.findPage(this.getWhereSql(condition),page,null);
        //设置扩展数据
        this.setCourseOpenExData(courseOpenPageInfo.getList(),userId,setSubjectData,setReservationData,setTeacherData,setCreateUserData);
        return courseOpenPageInfo;
    }

    /**
     * 获取一个当前正在直播的免费直播
     * @return CourseOpen
     */
    public CourseOpen findNowLiveCourseOpen(){
        CourseOpenCondition condition = new CourseOpenCondition();
        condition.setStatus(1);
        condition.setOpenLive(1);
        return this.findOne(this.getWhereSql(condition),null);
    }

    public void updateCourseOpenBespeakNum(BigDecimal id){
        CourseOpen courseOpen = new CourseOpen();
        this.updateByWhereSql(courseOpen," id = "+id);
    }
    public void updateCourseOpenAttendNum(BigDecimal id,Integer attendNum){
        CourseOpen courseOpen = new CourseOpen();
        courseOpen.setAttendNum(attendNum+1);
        this.updateByWhereSql(courseOpen," id = "+id);
    }

    //========================================

    private String getWhereSql(CourseOpenCondition condition){
        StringBuilder whereSql = new StringBuilder(" status!=3 ");
        if(ObjectUtils.isNotEmpty(condition)){
            if(StringUtils.isNotEmpty(condition.getCourseName())){
                whereSql .append(" and courseName like '%").append(condition.getCourseName().trim()).append("%'");
            }
            if(StringUtils.isNotEmpty(condition.getSubjectIds())){
                whereSql .append( StringUtils.getSubjectSql("subjectIds",condition.getSubjectIds()));
            }
            if(ObjectUtils.isNotEmpty(condition.getStatus()) && condition.getStatus().intValue()>0){
                whereSql .append(" and status=").append(condition.getStatus());
            }
            if(StringUtils.isNotEmpty(condition.getQueryIds())){
                String queryIds = StringUtils.subHeadTailString(condition.getQueryIds(),",");
                if(StringUtils.isNotEmpty(queryIds)){
                    whereSql .append(" and id in (").append(queryIds).append(")");
                }
            }
            if(condition.getOpenLive()==1){//开始直播
                whereSql .append(" and openTime <= now()");
                whereSql .append(" and endTime > now()");
            }
            if(ObjectUtils.isNotEmpty(condition.getNowDate())){//查询指定时间
                SimpleDateFormat time1 = new SimpleDateFormat("yyyy-MM-dd");
                whereSql .append( " and openTime >= '" ).append(time1.format(condition.getNowDate())).append(" 00:00:00'" ).append(
                        " and openTime <= '" ).append( time1.format(condition.getNowDate())).append( " 23:59:59'");
            }
        }
        whereSql .append(" order by createTime desc");
        return whereSql.toString();
    }

    /**
     * 设置免费直播的扩展数据
     * @param courseOpenList 免费直播列表
     * @param setSubjectData 是否设置专业
     * @param setTeacherData 是否设置讲师
     * @param setCreateUserData 是否设置创建人数据
     * @return List<CourseOpen>
     */
    private List<CourseOpen> setCourseOpenExData(List<CourseOpen> courseOpenList,BigDecimal userId, boolean setSubjectData, boolean setReservationData, boolean setTeacherData, boolean setCreateUserData){
        if(ObjectUtils.isNotEmpty(courseOpenList)){
            if(setSubjectData){//设置专业
                courseOpenList = commonSetSubjectDataService.setSubjectData(subjectService,courseOpenList,setSubjectData);
            }
            if(setCreateUserData){//设置创建人
                courseOpenList = commonSetCreateUserDataService.setSysUserData(sysUserService,courseOpenList,setCreateUserData);
            }
            if(setTeacherData){//设置讲师、助教1，助教2
                courseOpenList = setTeacherData(courseOpenList,setTeacherData);
            }
            if(setReservationData){
                //设置直播预约状态
                courseOpenList = this.setCourseOpenReservation(courseOpenList,userId);
            }
        }
        if(ObjectUtils.isNotEmpty(courseOpenList)){
            setDoMainName(courseOpenList);

        }

        //设置直播状态
        courseOpenList = this.setCourseOpenPlayStatus(courseOpenList);
        //设置直播路径
        courseOpenList = this.setCourseOpenPlayUrl(courseOpenList);
        //设置3T直播数据
        if(ObjectUtils.isNotEmpty(userId)){
            courseOpenList = this.setCourseOpen3TParamMap(userId,courseOpenList);
        }
        //设置直播账号
        this.setLiveAccount(courseOpenList);
        return courseOpenList;
    }

    /**
     * 设置直播是否预约
     * @param courseOpenList
     * @param userId
     * @return
     */
    private List<CourseOpen> setCourseOpenReservation(List<CourseOpen> courseOpenList,BigDecimal userId) {
        String ids = courseOpenList.stream().map(e-> e.getId().toString()).collect(Collectors.joining(","));
        List<CourseOpenBespeak> bespeakList = courseOpenBespeakBiz.find(" userId = "+ userId+" and openCourseId in("+ids+")",null,null);
        if(ObjectUtils.isNotEmpty(bespeakList)){
            Map<BigDecimal,CourseOpenBespeak> map = bespeakList.stream().collect(Collectors.toMap(e -> e.getOpenCourseId(),e -> e));
            courseOpenList.forEach(e -> {
                CourseOpenBespeak bespeak = map.get(e.getId());
                if(ObjectUtils.isNotEmpty(bespeak)){
                    e.setReservation(true);
                }else {
                    e.setReservation(false);
                }
            });
        }
        return courseOpenList;
    }



    /**
     * 设置直播账号
     * @param courseOpenList
     * @return List<CourseOpen>
     */
    private List<CourseOpen> setLiveAccount(List<CourseOpen> courseOpenList){

        if(ObjectUtils.isNotEmpty(courseOpenList)){
            TreeMap<String, String> VLASPROVIDER = sysConfigService.getSysConfigContext(ConfigName.VLASPROVIDER);
            TreeMap<String, String> V96K = sysConfigService.getSysConfigContext(ConfigName.V96K);
            courseOpenList.forEach(e->{
                if(e.getPlayType().equals("CC")){
                    e.setLiveAccount(VLASPROVIDER.get("ccAppId"));
                }
                else if(e.getPlayType().equals("96K")){
                    e.setLiveAccount(V96K.get("customerKey"));
                }
            });
        }
        return courseOpenList;
    }
    /**
     * 设置直播播放路径
     * @param courseOpenList
     * @return List<CourseOpen>
     */
    private List<CourseOpen> setCourseOpenPlayUrl(List<CourseOpen> courseOpenList){
        if(ObjectUtils.isNotEmpty(courseOpenList)){
            courseOpenList.forEach(e->{
                if (StringUtils.isEmpty(e.getStudentCode())) {
                    e.setPlayUrl("http://www.96koo.net/common/live/loginf.php?account=" + e.getRoomId() + "&role=user&freepassword=1&type=0&sign=" + e.getLiveUrl());
                } else {
                    e.setPlayUrl("https://www.96koo.net/common/live/Login.php?account=" + e.getRoomId() + "&role=user&type=0&sign=" + e.getLiveUrl());
                }
            });
        }
        return courseOpenList;
    }

    private List<CourseOpen> setCourseOpen3TParamMap(BigDecimal userId,List<CourseOpen> courseOpenList){
        if(ObjectUtils.isNotEmpty(courseOpenList)){
            Map<String,Object>  cusUserMap = cusUserService.userInfo(userId,false,false,false,false,false,false,false);
            courseOpenList.forEach(e->{
                if("TT".equals(e.getPlayType())){
                    e.setTLiveParams(getLiveParamMap(e,cusUserMap));
                }
            });
        }
        return courseOpenList;
    }

    private Map getLiveParamMap(CourseOpen courseOpen, Map<String, Object> userMap) {
        Map resultMap = new HashMap();
        try {
            Map params = new HashMap();
            params.put("classId", courseOpen.getRoomId());
            params.put("role", "3");
            params.put("uuid", userMap.get("id").toString());
            params.put("nickName", userMap.get("nickname"));
            params.put("avatar", userMap.get("avatar"));
            Map<String, Object> liveParamMap = ttServiceUtils.getLiveParam(params);
            if ((boolean) liveParamMap.get("success")) {
                Map entityMap = (Map) liveParamMap.get("entity");
                resultMap.put("roomId", entityMap.get("classId"));
                resultMap.put("userId", entityMap.get("UID"));
                resultMap.put("safeKey", entityMap.get("safeKey"));
                resultMap.put("timeStamp", entityMap.get("timeStamp"));
                resultMap.put("expiresIn", entityMap.get("expires_in"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMap;
    }

    /**
     * 设置直播状态
     * @param courseOpenList
     * @return List<CourseOpen>
     */
    private List<CourseOpen> setCourseOpenPlayStatus(List<CourseOpen> courseOpenList){
        if(ObjectUtils.isNotEmpty(courseOpenList)){
            Date currentTime = new Date();
            courseOpenList.forEach(e->{
                Date openTime = e.getOpenTime();
                Date endTime = e.getEndTime();
                if(endTime.before(currentTime)){//已结束
                    e.setPlayStatus(3);
                }
                if(openTime.before(currentTime) && endTime.after(currentTime)){//正在直播
                    e.setPlayStatus(1);
                }
                if(openTime.after(currentTime)){//未开始
                    e.setPlayStatus(2);
                }
            });
        }
        return courseOpenList;
    }

    /**
     * 设置讲师、助教1、助教2 数据
     * @param courseOpenList
     * @param setTeacherData
     * @return List<CourseOpen>
     */
    private List<CourseOpen> setTeacherData(List<CourseOpen> courseOpenList,boolean setTeacherData){
        if(ObjectUtils.isNotEmpty(courseOpenList) && setTeacherData){
            //得到讲师、助教1、助教2 的ID串
            String teacherIds = courseOpenList.stream().map(e->{
                return e.getTeacherId().toString() + (!DataUtil.idIsNotNull(e.getTutorOne())?"":","+e.getTutorOne()) + (!DataUtil.idIsNotNull(e.getTutorTwo())?"":","+e.getTutorTwo());
            }).collect(Collectors.joining(","));
            if(StringUtils.isNotEmpty(teacherIds)){
                Map<BigDecimal,Map<String,Object>> teacherMaps = sysTeacherService.findSysTeacherToMapByIds(teacherIds,false,false,false, false, false);
                if(ObjectUtils.isNotEmpty(teacherMaps)){
                    courseOpenList.forEach(e->{
                        if(DataUtil.idIsNotNull(e.getTutorOne())){
                            e.setTeacherOne(teacherMaps.get(e.getTutorOne()));
                        }
                        if(DataUtil.idIsNotNull(e.getTutorTwo())){
                            e.setTeacherTwo(teacherMaps.get(e.getTutorTwo()));
                        }
                        if(DataUtil.idIsNotNull(e.getTeacherId())){
                            e.setTeacher(teacherMaps.get(e.getTeacherId()));
                        }
                    });
                }
            }
        }
        return courseOpenList;
    }

    private void setDoMainName(List<CourseOpen> courseOpens) {
        for (CourseOpen open : courseOpens) {
            if (open.getPlayType().equals("96K")) {
                TreeMap<String, String> sysConfigContext = sysConfigService.getSysConfigContext(ConfigName.V96K);
                //设置专属域名 1.并发2.人次3.互动  96k直播计费方式
                if(ObjectUtils.isNotEmpty(open.getLiveBilling())){
                    switch (open.getLiveBilling()) {
                        case 1:
                            open.setDomainName(sysConfigContext.get("c_main"));
                            break;
                        case 2:
                            open.setDomainName(sysConfigContext.get("p_main"));
                            break;
                        case 3:
                            open.setDomainName(sysConfigContext.get("i_main"));
                            break;
                    }
                }
            }
        }
    }

    /**
     * 查询免费直播总数量数据
     * @return CourseOpenSumCount
     */
    public CourseOpenSumCount queryCourseOpenSumCount(){
        CourseOpenSumCount courseOpenSumCount = courseOpenDao.queryCourseOpenSumCount(CourseOpen.class);
        if(courseOpenSumCount==null){
            courseOpenSumCount = new CourseOpenSumCount();
        }
        return courseOpenSumCount;
    }

}
